#include "user_include.h"

#define ADC_CHANNEL_NUM 1
#define WEAR_DETECT_THRESHOLD 2500
static void user_init(void);
static void user_task(void);
static void user_control(uint8_t flag, ...);
/********voltage and percentage**************
100%----4.05V----2513  //4.1改成4.05 防止用户感觉电量使用过快
90%-----4.00V----2482
80%-----3.90V----2420
70%-----3.80V----2358
60%-----3.70V----2296
50%-----3.60V----2234
40%-----3.55V----2203
30%-----3.50V----2170
20%-----3.45V----2141
10%-----3.40V----2110
5%------3.35V----2079
0%------3.00V----1661
****/

static const uint16_t voltage_table[12] = {1661, 2079, 2110, 2141, 2170, 2203, 2234, 2296, 2358, 2420, 2482, 2513};
static const uint8_t percentage_table[12] = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
void *p_para[10];

struct driver_adc_struct_def driver_adc_struct = {
    .battery_level = 0,
    .init = user_init,
    .task = user_task,
    .control = user_control,
    .table = {0, 0, 0, 0},
};
/****************************************************************************
 * name:user_init
 * function: set the io to ad function
 * in parameters : no
 * out parameters : no
 ****************************************************************************/
static void user_init(void)
{
}

/****************************************************************************
 * name:adc_convert_level
 * function: return battery voltage
 * in parameters : ad value
 * out parameters : battery voltage
 ****************************************************************************/
static uint8_t adc_convert_level(uint16_t value)
{
    uint16_t i = 0;
    uint8_t ret = 0;

    if (value >= voltage_table[11])
    {
        ret = 100;
    }
    for (i = 0; i < 12; i++)
    {
        if (value < voltage_table[i])
        {
            ret = percentage_table[i];
            break;
        }
    }
    return ret;
}

/****************************************************************************
 * name:adc_convert_wearflag
 * function: detect whether people wear devices
 * in parameters : ad value
 * out parameters : 0 no wear 1 wear
 ****************************************************************************/
uint16_t adc_convert_wearflag(uint16_t value)
{
    uint16_t ret = 0;
    if (value > WEAR_DETECT_THRESHOLD)
    {
        ret = 1;
    }
    return ret;
}
/****************************************************************************
 * name:user_control
 * function:
 * in parameters : flag
 * out parameters : no
 ****************************************************************************/
void user_control(uint8_t flag, ...)
{
    va_list argptr;
    va_start(argptr, flag);
    p_para[0] = va_arg(argptr, int32_t *);
    p_para[1] = va_arg(argptr, int32_t *);
    p_para[2] = va_arg(argptr, int32_t *);
    p_para[3] = va_arg(argptr, int32_t *);
    p_para[4] = va_arg(argptr, int32_t *);
    p_para[5] = va_arg(argptr, int32_t *);
    p_para[6] = va_arg(argptr, int32_t *);
    p_para[7] = va_arg(argptr, int32_t *);
    va_end(argptr);
}
/****************************************************************************
 * name:driver_adc_convert_gas
 * function:
 * in parameters : flag
 * out parameters : no
 ****************************************************************************/
void driver_adc_convert_gas(int8_t index, int16_t value)
{
    int16_t res;
    switch (index)
    {
    case (0):
    {
    }
    break;
    case (1):
    {
    }
    break;
    case (2):
    {
    }
    break;
    case (3):
    {
    }
    break;
    default:
        res = 0;
    }
}

/****************************************************************************
 * name:driver_adc_convert_task
 * function: sample and convert function
 * in parameters : no
 * out parameters : no
 ****************************************************************************/
static void user_task(void)
{
    uint8_t state = 0;
    uint16_t sample_times[ADC_CHANNEL_NUM];
    uint32_t sample_sum[ADC_CHANNEL_NUM];
    uint32_t buffer[ADC_CHANNEL_NUM];
    uint8_t i = 0;
    uint16_t temp = 0;

    while (1)
    {
        osDelay(10);
        switch (state)
        {
        case (0):
        {
            for (i = 0; i < ADC_CHANNEL_NUM; i++)
            {
                sample_times[i] = 0;
                sample_sum[i] = 0;
            }
            state = 1;
        }
        break;
        case (1):
        {
            // HAL_ADC_Stop_DMA(&hadc1);
            HAL_ADC_Start_DMA(&hadc1, buffer, 1);
            state = 2;
        }
        break;
        case (2):
        {
            temp = buffer[0]; // recv data
            sample_sum[0] += temp;
            sample_times[0]++;
            if (sample_times[0] >= 10)
            {
                sample_sum[0] /= sample_times[0];
                driver_adc_struct.table[0] = sample_sum[0];
                driver_adc_struct.table[1] = sample_sum[0] / 2;
                driver_adc_struct.table[2] = 2048;
                driver_adc_struct.table[3] = 0;
                sample_times[0] = 0;
                sample_sum[0] = 0;
            }
            state = 1;
        }
        break;
        default:
            state = 0;
        }
    }
}
